package com.kd.data.transport;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.kdtech.rpc.RPCClient;
import com.kdtech.rpc.intface.IndexCreateTaskQueueInterface;
import com.kdtech.utils.FileUtils;
import com.kdtech.utils.PropertiesUtils;
import com.kdtech.utils.StringUtils;
import com.kdtech.utils.ZipUtils;

public class DataIndexThread extends Thread {

	private static final Logger logger=Logger.getLogger(DataIndexThread.class);	
	
	private static final Properties pro = PropertiesUtils.getProperties("data_index.properties");
	private String dirName = null;
	private static final String extension = pro.getProperty("file.extension", ".txt");
	private IndexCreateTaskQueueInterface indexCreateClient = null;
	private volatile boolean isRunnable = false;
	private int scanTime = 6;
	private boolean isBackuped = Boolean.parseBoolean(pro.getProperty("isBackuped", "false"));
	private String backup = pro.getProperty("backup.dir", "D:/kd-xj/backup-file");
	
	private String dataIndexName = "Data-index-Thread";
	
	public DataIndexThread(String host, int port, String dirName, String dataIndexName, int scanTime) {
		this.dirName = dirName;
		this.dataIndexName = dataIndexName;
		this.scanTime = scanTime;
		try {
			RPCClient<IndexCreateTaskQueueInterface> rpcIndexCreate = new RPCClient<IndexCreateTaskQueueInterface>(IndexCreateTaskQueueInterface.class, host, port);
			indexCreateClient = rpcIndexCreate.getClient();
			logger.info(this.dataIndexName + " has connect remote Server[" + host + ":" + port + "]");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public DataIndexThread(String host, int port, String dirName, int scanTime) {
		this(host, port, dirName, "Data-index-Thread", scanTime);
	}

	@Override
	public void run() {
		if(null==dirName || "".equals(dirName)) {
			throw new RuntimeException(dataIndexName + ": Data directory is null, please config it in file[data_index.properties] again!");
		}
		
		isRunnable = true;
		
		while(isRunnable) {
			try {
				DirLock.getInstance().acquire();
				todo();
				DirLock.getInstance().release();
				try {
					Thread.sleep(scanTime);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (Exception e) {
				logger.error("inserting the file to index-server happen to error.", e);
			}
		}
	}
	public void todo() {
		List<String> filePaths = new ArrayList<String>();
		FileUtils.getAllFileNames(dirName, filePaths);
		for(String path : filePaths) {
			if(StringUtils.isBlank(path) || !path.endsWith(extension)) {
				continue ;
			}
			logger.info(dataIndexName + ": start to index the file[" + path + "]");
			if(doDataIndex(path)) {
				//first: backup
				if(isBackuped) {
					File backupFile = new File(backup);
					if(null==backup || "".equals(backup) || !backupFile.exists() || !backupFile.isDirectory()) {
						throw new RuntimeException(dataIndexName + ": Back up Data directory is null, if you need backup, please config it in file[data_index.properties] again!");
					}
					
					File file = new File(path);
					if(file.isFile()) {
						int beginIndex = path.lastIndexOf("\\", path.indexOf(file.getName())-2) + 1;
						int endIndex = path.lastIndexOf("\\");
						String dateDir = path.substring(beginIndex, endIndex);
						String destPath = backupFile.getPath() + "/" + dateDir.replace("_", "");
						if(backup(path, destPath)) {
							FileUtils.delete(path);
						}
					}
				} else {
					//second: delete
					FileUtils.delete(path);
				}
			}
			logger.info(dataIndexName + ": finish to index the file[" + path + "]");
		}
		filePaths.clear();
		filePaths = null;
	}
	
	public boolean doDataIndex(String path) {
		if(null==path || "".equals(path)) {
			return false;
		}
		boolean success = false;
		try {
			String encoding = pro.getProperty("encoding", "UTF-8");
			String data = FileUtils.file2String(new File(path), encoding);
			System.out.println("Json data: " + data);
			// old version
//			IndexMeta meta = JSONArray.parseObject(data, IndexMeta.class);
//			System.out.println("content: " + meta.getContent());
//			byte[] dataBytes = StringUtils.ZipObject(meta);
			// new version
			byte[] dataBytes = ZipUtils.gzip(data).getBytes("UTF-8");
			indexCreateClient.AddCreateIndexTask(dataBytes);
			success = true;
		} catch (Exception e) {
			logger.error(dataIndexName + " has happen to an exception for index server at the file[" + path + "]", e);
			success = false;
		}
		return success;
	}
	
	public boolean backup(String srcPath, String destPath) {
		if(null==srcPath || "".equals(srcPath)) {
			return false;
		}
		if(null==destPath || "".equals(destPath)) {
			return false;
		}
		// Destination directory
		File srcFile = new File(srcPath);
        File destFile = new File(destPath);
        if(!destFile.exists()) {
        	destFile.mkdir();
        }
        // Move file to new directory
        boolean success = FileUtils.CopySingleFileTo(srcFile.getPath(), destFile.getPath());
        logger.info((success? "Success" : "Failed" ) + " to backup the file[" + destFile.getPath() + "\\" + srcFile.getName() + "]");
        return success;
	}
	
	public void toStop() {
		isRunnable = false;
	}
	
}
